
#ifndef DXAPP_H
#define DXAPP_H

#include <D3D11.h>
#include <cassert>
#include <Windows.h>
#include <vector>
#include <AntTweakBar.h>
#include <d3dx11Effect.h>
using std::vector;

class DXApp
{
	
	public:
		DXApp();
		virtual ~DXApp();

		virtual bool initialise(HINSTANCE instance, int cmdShow);

		virtual void renderScene(float dt) = 0;
		virtual void updateScene() = 0;
		virtual void onKey(WPARAM wParam) = 0;
		virtual void onMouseWheel(WPARAM wParam);
		virtual void onLMouseClick(LPARAM lParam);
		virtual void onRMouseClick(LPARAM lParam);
		virtual void onLMouseDrag(int oldX, int oldY, int newX, int newY);

		virtual HRESULT onResize(int width, int height);

		static HINSTANCE hApp() { assert(_instance); return _instance->_hApp; }
		static HWND hWnd() { assert(_instance); return _instance->_hWnd; }

		bool loadEffect(const char* filename, std::vector<char> &compiledShader) const;
		void setupViewport();
		void resetStates();
		void bindFrameBuffer();

		void startTimer();
		double getDeltaTime();

		ID3D11Device* g_dev() const { return _dxDev; }
		ID3D11DeviceContext* g_context() const { return _dxImmedDC; }
		IDXGISwapChain* g_swapChain() const { return _swapChain; }

		void setWidth(int w) { _width = w; }
		void setHeight(int h) { _height = h; }

		int getWidth() const { return _width; }
		int getHeight() const { return _height; }

		// Effect Variables Setters
		// __ Matrices
		static bool setMatrixVar(ID3DX11Effect* fx, const void*       mtx, const char* var_name);
		// __Vectors
		static bool setVectorVar(ID3DX11Effect* fx, const void* data,    const char* var_name);
		// __Srv
		static bool setSrvVar(ID3DX11Effect* fx, ID3D11ShaderResourceView* srv, const char* var_name);
		static bool setSrvArrayVar(ID3DX11Effect* fx, ID3D11ShaderResourceView** srv, const char* var_name, unsigned int offset, unsigned int count);
		// __Scalars
		static bool setFloatVar(ID3DX11Effect* fx, float data, const char* var_name);
		static bool setIntVar(ID3DX11Effect* fx, int data, const char* var_name);
		static bool setBoolVar(ID3DX11Effect* fx, bool data, const char* var_name);



	private:
		static LRESULT CALLBACK MessageProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam);

		ID3D11Device *_dxDev;
		ID3D11DeviceContext *_dxImmedDC;
		IDXGISwapChain *_swapChain;

		DXGI_SWAP_CHAIN_DESC _swapChainDesc;
	
		ID3D11RenderTargetView *_renderTargetView;
		ID3D11DepthStencilView *_depthStencilView;
		D3D11_TEXTURE2D_DESC _depthStencilDesc;

		__int64 start; 
		double freq; 

		HRESULT initialiseDxDevice();
		HRESULT createDepthStencilView();
		HRESULT createRenderTargetView();

		static int mouseDownX, mouseDownY;
		
		int _width;
		int _height;


		static DXApp* _instance;
		HINSTANCE _hApp;
		HWND _hWnd;

};



#endif